package com.whl215.customview.jk

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
import android.view.View
import android.view.animation.OvershootInterpolator
import com.whl215.customview.R

/**
 * 点赞View
 * 因为是高度定制化的view 所有没有开放式属性修改图片
 */
class ThumbsUpView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), ITouchAnimInterface {
    private val bmpSelected: Bitmap by lazy {
        BitmapFactory.decodeResource(
            getContext().resources,
            R.drawable.ic_thumbs_up_selected
        )
    }
    private val bmpUnSelected: Bitmap by lazy {
        BitmapFactory.decodeResource(
            getContext().resources,
            R.drawable.ic_thumbs_up_unselected
        )
    }
    private val bmpShining: Bitmap by lazy {
        BitmapFactory.decodeResource(
            getContext().resources,
            R.drawable.ic_thumbs_up_shining
        )
    }

    //是否测量完成
    private var isMeasured = false

    //竖条 透明
    private var mShiningAlphaValue = 0

    //扩散圆环透明度
    private var mCircleAlphaValue = 0

    //扩散圆环 半径
    private var mCircleRadiusValue = 0f

    //中心原点
    private val mCenterPoint = Point()
    private val mPaint: Paint by lazy { Paint() }
    private val mPaintCircle: Paint by lazy { Paint() }

    //圆环透明度
    private val mAnimCircleAlpha: ValueAnimator by lazy {
        val startValue = 80
        val endValue = 0
        val animator = ObjectAnimator
            .ofInt(startValue, endValue)
        animator.addUpdateListener {
            mCircleAlphaValue = it.animatedValue.toString().toInt()
            invalidate()
        }
        return@lazy animator
    }

    //圆环半径
    private val mAnimCircleRadius: ValueAnimator by lazy {
        val radius = mCenterPoint.x.toFloat()
        val animator = ObjectAnimator
            .ofFloat(radius - 15, radius)
        animator.addUpdateListener {
            mCircleRadiusValue = it.animatedValue.toString().toFloat()
            invalidate()
        }
        return@lazy animator
    }

    //竖条 淡入
    private val mAnimShiningFadeIn: ValueAnimator by lazy {
        val animator =
            ObjectAnimator
                .ofInt(0, 255)
        animator.addUpdateListener {
            mShiningAlphaValue = it.animatedValue.toString().toInt()
            invalidate()
        }
        return@lazy animator
    }

    //竖条 淡出
    private val mAnimShiningFadeOut: ValueAnimator by lazy {
        val animator =
            ObjectAnimator
                .ofInt(255, 0)
                .setDuration(100)
        animator.addUpdateListener {
            mShiningAlphaValue = it.animatedValue.toString().toInt()
            invalidate()
        }
        return@lazy animator
    }

    //点赞状态
    var checked: Boolean = false
        set(value) {
            field = value
            //选中状态改变启动动画，
            //特殊情况：为了节省资源，并且控制动画的声明周期，将动画改成懒加载全局变量
            // 某种情况下 view绘制过程并没有完成，给view设置初始值，调用setter
            // 动画初始化 取不到view的宽度，在动画中会使用view宽高，导致异常
            if (isMeasured){
                startCircleRadiusAnim()
                startCircleAlphaAnim()
                startShinAlphaAnim()
            }
        }

    init {
        mPaint.isAntiAlias = true
        mPaintCircle.isAntiAlias = true
        mPaintCircle.style = Paint.Style.STROKE
        mPaintCircle.strokeWidth = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            3f,
            context.resources.displayMetrics
        )
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var resultWidth: Int
        var resultHeight: Int
        val shinWidth = bmpShining.width
        val shinHeight = bmpShining.height
        val selectedWidth = bmpSelected.width
        val selectedHeight = bmpSelected.height
        resultWidth = if (shinWidth > selectedWidth) shinWidth else selectedWidth
        resultHeight = shinHeight + selectedHeight
        //要画一个扩散的⚪ 所以考虑把view设置正方形 作为圆形扩散的留白
        if (resultHeight > resultWidth) resultWidth = resultHeight else resultHeight = resultWidth
        mCenterPoint.x = resultWidth / 2
        mCenterPoint.y = resultHeight / 2
        setMeasuredDimension(resultWidth, resultHeight)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        isMeasured = true
    }


    override fun onDraw(canvas: Canvas?) {
        val shiningHeight = (bmpShining.height / 2).toFloat()
        val shiningLeftPoint = (width / 2 - bmpShining.width / 2).toFloat()
        val likeLeftPoint = (width / 2 - bmpSelected.width / 2).toFloat()
        canvas?.let {
            mPaint.alpha = mShiningAlphaValue
            it.drawBitmap(bmpShining, shiningLeftPoint, 0f, mPaint)
            mPaint.alpha = 255
            if (checked) {
                it.drawBitmap(bmpSelected, likeLeftPoint, shiningHeight, mPaint)
                mPaintCircle.setARGB(mCircleAlphaValue, 228, 88, 62)
                canvas.drawCircle(
                    mCenterPoint.x.toFloat(),
                    mCenterPoint.y.toFloat(),
                    mCircleRadiusValue,
                    mPaintCircle
                )
            } else {
                it.drawBitmap(bmpUnSelected, likeLeftPoint, shiningHeight, mPaint)
            }
        }
    }


    private fun startShinAlphaAnim() {
        if (checked) {
            mAnimShiningFadeIn.start()
        } else {
            mAnimShiningFadeOut.start()
        }
    }

    private fun startCircleAlphaAnim() {
        mAnimCircleAlpha.start()
    }

    private fun startCircleRadiusAnim() {
        mAnimCircleRadius.start()
    }


    override fun onDetachedFromWindow() {
        if (!bmpSelected.isRecycled) bmpSelected.recycle()
        if (!bmpUnSelected.isRecycled) bmpSelected.recycle()
        if (!bmpShining.isRecycled) bmpSelected.recycle()
        if (mAnimCircleAlpha.isRunning) mAnimCircleAlpha.cancel()
        if (mAnimCircleRadius.isRunning) mAnimCircleRadius.cancel()
        if (mAnimShiningFadeIn.isRunning) mAnimShiningFadeIn.cancel()
        if (mAnimShiningFadeOut.isRunning) mAnimShiningFadeOut.cancel()
        super.onDetachedFromWindow()

    }

    override fun startAnim(isDown: Boolean) {
        if (isDown) {
            animate()
                .scaleX(0.75f)
                .scaleY(0.75f)
                .start()
        } else {
            clearAnimation()
            scaleX = 0.75f
            scaleY = 0.75f
            animate()
                .scaleX(1f)
                .scaleY(1f)
                .setInterpolator(OvershootInterpolator())
                .start()

        }
    }


}